/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/cat.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../data_struct/head.h"
#include "../config/head.h"
#include "../macro/head.h"
#include "../impl/head.h"
#include "../impl/head.h"
#include "../msg/head.h"
#include "helper_pass_through.h"

namespace cat
{

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    typedef std::vector< xos::i_callback* > THREAD_VECT;
    typedef THREAD_VECT::iterator THREAD_ITER;

    static THREAD_VECT * pass_through_vect_ptr = 0;

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    helper_pass_through::helper_pass_through()
    {
    }

    helper_pass_through::~helper_pass_through()
    {
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int helper_pass_through::add_thread( xos::i_callback * pThread )
    {
        int ret = 0;
        pass_through_vect_ptr->push_back( pThread );
        return ret;
    }

    int helper_pass_through::init()
    {
        int ret = 0;

        if( 0 == ret )
        {
            ret = xos_stl::init_obj( pass_through_vect_ptr );
        }

        if( 0 == ret )
        {
            add_thread( mgr::xos()->log_thread() );
        }

        return ret;
    }

    int helper_pass_through::term()
    {
        int ret = 0;

        xos_stl::term_obj( pass_through_vect_ptr );

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int helper_pass_through::pass_through_impl( xos::i_msg *& pMsg )
    {
        int ret = 0;

        int nSize = ( int )pass_through_vect_ptr->size();
        int nIdx = pMsg->get_int( 1, 0 );

        nIdx++;

        if( nIdx < nSize )
        {
            xos::i_callback * pT = pass_through_vect_ptr->at( nIdx );
            pMsg->set_int( 1, nIdx );
            pT->notify( pMsg );
        }
        else
        {
            pop( pMsg );
            mgr::notify( pMsg, false );
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 

    int helper_pass_through::proc( xos::i_msg *& pMsg )
    {
        int result = 1;
        int ret = 0;

        if( ( 0 == ret ) && ( MAIN_PASS_THROUGH != pMsg->get_int( 0, 0 ) ) )
        {
            result = 0;
            ret = 1;
        }

        if( 0 == ret )
        {
            ret = pass_through_impl( pMsg );
        }

        return result;
    }

    int helper_pass_through::push( xos::i_msg *& pMsg )
    {
        xos::i_msg * pOuterMsg = mgr::xos()->msg();
        msg::fill( pOuterMsg, THREAD_TYPE_MAIN, MSG_TYPE_MAIN, MAIN_PASS_THROUGH, false );
        pOuterMsg->set_int( 1, -1 );
        pOuterMsg->set_void( 0, pMsg );
        pMsg = pOuterMsg;
        return 0;
    }

    int helper_pass_through::pop( xos::i_msg *& pMsg )
    {
        xos::i_msg * pInnerMsg = ( xos::i_msg * )pMsg->get_void( 0, 0 );
        xos::i_msg * pTemp = pMsg;
        pMsg = pInnerMsg;
        pTemp->release();
        return 0;
    }

} // cat
